package org.brisling.sysman.service;

import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.net.URL;
import java.net.URLEncoder;
import java.security.KeyManagementException;
import java.security.NoSuchAlgorithmException;
import java.security.cert.CertificateException;
import java.security.cert.X509Certificate;
import java.util.HashMap;
import java.util.List;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;

import javax.net.ssl.HostnameVerifier;
import javax.net.ssl.HttpsURLConnection;
import javax.net.ssl.SSLContext;
import javax.net.ssl.SSLSession;
import javax.net.ssl.TrustManager;
import javax.net.ssl.X509TrustManager;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.brisling.base.domain.ListDomain;
import org.brisling.base.domain.RetDomain;
import org.brisling.common.ConstSysParam;
import org.brisling.common.SysConfig;
import org.brisling.oa.domain.OAAddressList;
import org.brisling.oa.queryService.QueryOAAddressListService;
import org.brisling.sysman.domain.SysShortMessage;
import org.brisling.sysman.repository.ShortMessageRepo;
import org.brisling.sysman.service.base.BaseSysmanService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.servlet.ModelAndView;


@RestController
@RequestMapping("/sms")
/**
 * 
 * <p>Title: ShortMessageService</p>
 * <p>Description: 短信服务接口</p>
 * <p>Company: 长沙东勤信息科技发展有限公司</p>
 * @author jackson wang
 * @since 1.0
 * @version 1.0
 * @date 2019年8月2日 下午2:55:47
 */
public class ShortMessageService extends BaseSysmanService<SysShortMessage>{
	
	
	private final static Log log=LogFactory.getLog(ShortMessageService.class);
	
	private  ExecutorService smsThreadPool = Executors.newFixedThreadPool(5);
	
	@Autowired
	private ShortMessageRepo baseRepo;	
	
	@Autowired
	private QueryOAAddressListService qryOAAddressListService;
	
	//缺省为昂楷接口位置
	private String _url = "https://192.168.1.240/services/riskManager/shortMessage";
	
	
	public ShortMessageService(){
		this.moduleName = ConstSysParam.MODULE_SHORTMESSAGE;
	}
	
	
	//获取端口及ip配置
	private void getSmsConfig(){
		String _config = SysConfig.getConfig("smsConfig");
		if(_config!=null && _config.trim().length()>0){
			_url = _config.trim();			
		}
	}
	
	/**
	 * 获取业务主页面 
	 * @return
	 */
	@RequestMapping("/mainPage.action")
	public ModelAndView getMainPage(){
		return getBizMainPage();
	}
	
	/**
	 * 获取业务编辑页面
	 * @return
	 */
	@RequestMapping("/editPage.action")
	public ModelAndView getEditPage(){
		return getBizEditPage();
	}
	
	
	/**
	 * 分页查询短信息内容
	 * @param page
	 * @param rows
	 * @param sort
	 * @return
	 */
	@RequestMapping("/getListDomain.action")
	public ListDomain<SysShortMessage> getListDomain(
			@RequestParam(value="page",required=false) String page,
			@RequestParam(value="rows",required=false) String rows,
			@RequestParam(value="sort",required=false) String sort){
		
				
		return super.getPagedList(page, rows);
			
	}
	
	/**
	 * 分页查询用户列表页面
	 * @param deptid
	 * @param page
	 * @param rows
	 * @param sort
	 * @return
	 */
	@RequestMapping("/getList.action")
	public List<SysShortMessage> getList(
			@RequestParam(value="page",required=false) String page,
			@RequestParam(value="rows",required=false) String rows,
			@RequestParam(value="sort",required=false) String sort){
		
		
			return super.getAll(page,rows,getSort(sort));
			
	}
	
	
	/**
	 * 删除记录,单条或批量删除记录,id不为空，执行单条删除，id为空且ids不为空，执行批量删除
	 * @param id	待删除的单条记录id
	 * @param ids	待删除的多条记录id，以','分隔
	 * @return
	 */
	@RequestMapping("/del.action")
	public RetDomain delRow(@RequestParam(value="id",required=false) Long id,@RequestParam(value="ids",required=false) String ids){
				
		return super.delRows(id, ids);		 
	}
	
	/**
	 * 删除记录,单条或批量删除记录,id不为空，执行单条删除，id为空且ids不为空，执行批量删除
	 * @param id	待删除的单条记录id
	 * @param ids	待删除的多条记录id，以','分隔
	 * @return
	 */
	@RequestMapping("/flowDel.action")
	public RetDomain delFlowRow(@RequestParam(value="id",required=false) Long id,@RequestParam(value="ids",required=false) String ids){
		
			return delRow(id,ids);
		
	}
	
	
	/**
	 * 保存系统参数
	 * @param id
	 */
	@RequestMapping("/save.action")
	public SysShortMessage save(@RequestBody String body){
		SysShortMessage obj = bodyToObj(body, SysShortMessage.class);		
		super.save(obj);
		
		if(obj!=null && obj.getId()!=null){
			return this.getOne(obj.getId());
		}
		return obj;
	}
	
	
	/**
	 * 定时发送短信
	 */
	public void timingSend(){
		HashMap<String,Object> param = new HashMap<String,Object>();
		param.put("sendStatus", "0");
		List<SysShortMessage> lists = baseRepo.getBySendStatus("0");
		
		if(lists!=null && lists.size()>0){
			log.debug("------------ shortMessageService calling send --------------");
			for(SysShortMessage s:lists){
				this.sendMsg(s);
				log.debug("------------ shortMessageService called send --------------");
			}
		}
	}
	/**
	 * 调用短信接口发送短信
	 * @param domain
	 * @return
	 */	
	public void sendMsg(SysShortMessage domain){
		
		//判断参数是否完整
		if(domain!=null &&  domain.getMessageContent()!=null){
			
			String _phone = domain.getPhoneNumber();
//			log.debug("------------ shortMessageService get domain phoneNumber: " + _phone);
			//根据用户id获取电话号码
			if(_phone == null || _phone.trim().length()<=0){
				String uid = domain.getUserid();
				OAAddressList  addr= qryOAAddressListService.getOne(uid);
//				log.debug("------------ shortMessageService get addr mobile,  uid: " +  uid );
				
				if(addr!=null && addr.getMobile()!=null){
//					log.debug("------------ shortMessageService get addr mobile: "+ addr.getMobile());
					domain.setPhoneNumber(addr.getMobile());
				}
			}
			
			//判断电话号码是否存在
			if(domain.getPhoneNumber()!=null ){
				this.getSmsConfig();
				
				
				domain.setSendStatus("1");
				super.save(domain);
				
				try {
					this.sendHttpsGet(_url, domain.getMessageContent(), domain.getPhoneNumber(), "utf8");
				} catch (KeyManagementException e) {
					// TODO Auto-generated catch block
					e.printStackTrace();
				} catch (NoSuchAlgorithmException e) {
					// TODO Auto-generated catch block
					e.printStackTrace();
				} catch (IOException e) {
					// TODO Auto-generated catch block
					e.printStackTrace();
				}				
			}
		}
		
	}
	
	
	/**
	 * post方式请求服务器(https协议)
	 * 
	 * @param url
	 *            请求地址
	 * @param content
	 *            参数
	 * @param charset
	 *            编码
	 * @return
	 * @throws NoSuchAlgorithmException
	 * @throws KeyManagementException
	 * @throws IOException
	 */
	public byte[] sendHttpsGet(String url, String content, String phoneNumber,String charset)
			throws NoSuchAlgorithmException, KeyManagementException, IOException {
		SSLContext sc = SSLContext.getInstance("SSL");
		sc.init(null, new TrustManager[] { new TrustAnyTrustManager() }, new java.security.SecureRandom());
		
		
		//utf8编码接口访问地址
		String _content = URLEncoder.encode(content,"UTF-8");
		
		String _url = String.format("%1$s/%2$s/%3$s", url,_content,phoneNumber);
		URL console = new URL(_url);
		HttpsURLConnection conn = (HttpsURLConnection) console.openConnection();
		conn.setSSLSocketFactory(sc.getSocketFactory());
		conn.setHostnameVerifier(new TrustAnyHostnameVerifier());
		conn.setDoOutput(true);
		conn.setDoInput(true);
		conn.setRequestMethod("GET");
		conn.connect();
		
		InputStream is = conn.getInputStream();
		if (is != null) {
			ByteArrayOutputStream outStream = new ByteArrayOutputStream();
			byte[] buffer = new byte[1024];
			int len = 0;
			while ((len = is.read(buffer)) != -1) {
				outStream.write(buffer, 0, len);
			}
			is.close();
			is = null;
			
			return outStream.toByteArray();
		}
		
		conn.disconnect();

		return null;
	}
	
	private static class TrustAnyTrustManager implements X509TrustManager {

		public void checkClientTrusted(X509Certificate[] chain, String authType) throws CertificateException {
		}

		public void checkServerTrusted(X509Certificate[] chain, String authType) throws CertificateException {
		}

		public X509Certificate[] getAcceptedIssuers() {
			return new X509Certificate[] {};
		}
	}
	
	private static class TrustAnyHostnameVerifier implements HostnameVerifier {
		public boolean verify(String hostname, SSLSession session) {
			return true;
		}
	}

	
	
}
